package gnss

const (
	U8_0  byte   = 0
	U8_1  byte   = 1
	U32_1 uint32 = 1
	U32_0 uint32 = 0
	U64_1 uint64 = 1
	U64_0 uint64 = 0
	I64_1 int64  = 1
)

// 第一位作为符号位
func GetBitI32(buf []byte, startBitN int, l int) int32 {
	ru := GetBitU(buf, startBitN, l)
	if l <= 0 || l >= 32 {
		return int32(ru)
	}

	if ru&uint32(U32_1<<uint(l-1)) == 0 {
		return int32(ru)
	}

	v := ^U32_0

	v = uint32(v << uint(l))
	rval := ru | v

	return int32(rval)
}

// 第一位作为符号位
func GetBitI64(buf []byte, startBitN int, l int) int64 {
	ru := GetBitU64(buf, startBitN, l)
	if l <= 0 || l >= 64 {
		return int64(ru)
	}

	if ru&uint64(U64_1<<uint(l-1)) == 0 {
		return int64(ru)
	}

	v := ^U64_0

	v = uint64(v << uint(l))
	rval := ru | v

	return int64(rval)
}

func GetBitI8(buf []byte, startBitN int, l int) int8 {
	return int8(GetBitI32(buf, startBitN, l))
}

func GetBitI16(buf []byte, startBitN int, l int) int16 {
	return int16(GetBitI32(buf, startBitN, l))
}

func GetBitU(buf []byte, startBitN int, l int) uint32 {
	//var rval uint = 0;
	//for i := startBitN; i < startBitN+l; i++ {
	//	b := buf[i/8];
	//	n := (7-i%8);
	//	b = byte(b >> byte(n));
	//	b = b & 1;    // 获取最低位
	//	rval = rval <<1 + uint(b);
	//}
	//return rval;
	return uint32(GetBitU64(buf, startBitN, l))
}

func GetBitU8(buf []byte, startBitN int, l int) byte {
	return byte(GetBitU64(buf, startBitN, l))
}

// 注 1：符号数值表示记录数据的符号和数值。最高有效位 MSB 为 0 表示正数，为 1 表示负数，其余位是数据的数值。
func GetBitG(buf []byte, startBitN int, l int) float64 {
	rval := float64(GetBitU(buf, startBitN+1, l-1))
	if GetBitU(buf, startBitN, 1) == 0 {
		return rval
	} else {
		return -rval
	}

}

func GetBitU32(buf []byte, startBitN int, l int) uint32 {
	return uint32(GetBitU64(buf, startBitN, l))
}

func GetBitU16(buf []byte, startBitN int, l int) uint16 {
	return uint16(GetBitU64(buf, startBitN, l))
}

// 小端法
func GetBitU64(buf []byte, startBitN int, l int) uint64 {
	var rval uint64 = 0
	for i := startBitN; i < startBitN+l; i++ {
		b := buf[i/8]
		n := (7 - i%8)
		b = byte(b >> byte(n))
		b = b & 1 // 获取最低位
		rval = rval<<1 + uint64(b)
	}
	return rval
}

func SetBitI8(buf []byte, startBitN int, l int, val int8) {
	SetBitI64(buf, startBitN, l, int64(val))
}

func SetBitI32(buf []byte, startBitN int, l int, val int32) {
	SetBitI64(buf, startBitN, l, int64(val))
}

func SetBitU32(buf []byte, startBitN int, l int, val uint32) {
	SetBitU64(buf, startBitN, l, uint64(val))
}

func SetBitU8(buf []byte, startBitN int, l int, val uint8) {
	SetBitU64(buf, startBitN, l, uint64(val))
}

func SetBitU16(buf []byte, startBitN int, l int, val uint16) {
	SetBitU64(buf, startBitN, l, uint64(val))
}

func SetBitI64(buf []byte, startBitN int, l int, val int64) {
	if val < 0 {
		val |= I64_1 << uint8(l-1)
	} else {
		val &= ^(I64_1 << uint8(l-1))
	}
	SetBitU64(buf, startBitN, l, uint64(val))
}

func SetBitU64(buf []byte, startBitN int, l int, val uint64) {
	if l <= 0 || 64 < l {
		return
	}
	mask := U64_1 << (uint64(l) - 1)
	for i := startBitN; i < startBitN+l; i++ {
		bitN := uint8(7 - i%8)
		v := buf[i/8]
		m := byte(U64_1 << bitN)
		if val&mask > 0 {
			buf[i/8] = v | m
		} else {
			buf[i/8] &= ^m
		}
		mask >>= 1
	}
}

//
//func SetBitN_U8(v byte, startBitN int, l, n int, bitv byte) byte {
//	if l <= 0 || l > 8 {
//		return v
//	}
//
//	if n < 0 || n > 8 {
//		return v
//	}
//
//	mask := U8_1 << byte(l-1-n)
//	if bitv == 0 {
//		v &= ^mask;
//	}else{
//		v |= mask;
//	}
//	return v;
//}
